﻿using HttpMethod = Devonline.Core.HttpMethod;

namespace Devonline.Identity;

/// <summary>
/// 用户认证上下文
/// 用户单个资源的授权缓存
/// 网关+认证+授权 的模式下, 用户授权信息的初始条件除了用户名只有当前请求的资源地址, 其余用户授权相关信息都需要通过查询缓存得到
/// </summary>
public class UserAuthorizationContext
{
    /// <summary>
    /// 用户编号
    /// </summary>
    public string UserId { get; set; } = null!;
    /// <summary>
    /// 用户名
    /// </summary>
    public string UserName { get; set; } = null!;
    /// <summary>
    /// 用户状态, 正常情况下为可用状态, 第三方认证的用户, 在尚未注册系统账户时为草稿状态
    /// </summary>
    public DataState UserState { get; set; }
    /// <summary>
    /// 授权资源编号
    /// </summary>
    public string? ResourceId { get; set; }
    /// <summary>
    /// 资源访问地址
    /// </summary>
    public string Path { get; set; } = null!;
    /// <summary>
    /// 资源编号
    /// </summary>
    public string? Code { get; set; }
    /// <summary>
    /// HttpMethod
    /// </summary>
    public HttpMethod? HttpMethod { get; set; }
    /// <summary>
    /// 当前资源是否已授权, 这是自动判断的授权策略, 表示当前资源已分配了权限, 允许访问
    /// </summary>
    public bool IsAuthorized { get; set; }
    /// <summary>
    /// 当前资源是否需要授权访问, 根据资源的访问规则决定
    /// </summary>
    public bool? IsAuthorizeAccess { get; set; }
    /// <summary>
    /// 当前用户是否取得当前资源的访问授权
    /// 如果 IsAuthorizeAccess = true 则需要 IsAuthorized = true && HasAuthorizeAccess = true 才能访问
    /// HasAuthorizeAccess 值的意义:
    /// null: 尚未取得授权
    /// true: 已取得授权, 且已授权访问
    /// false: 已取得授权, 但被拒绝访问
    /// </summary>
    public bool? HasAuthorizeAccess { get; set; }
    /// <summary>
    /// 访问次数限制, 记录剩余的可访问次数, 这里的访问次数仅记录当前资源所有匹配的访问规则中访问次数限制数目最小的一个, 在每次访问后减少 1, 直到访问次数为 0 时, 访问被拒绝
    /// </summary>
    public int? AccessCount { get; set; }
    /// <summary>
    /// 过期时间限制, 记录当前资源的过期时间, 这里的访问时间限制仅记录当前资源所有匹配的访问规则中过期时间最近的一个, 在每次访问后检查当前时间是否超过过期时间, 超过则访问被拒绝
    /// </summary>
    public DateTime? ExpireTime { get; set; }
    /// <summary>
    /// 是否存在访问条件限制, 每一个访问规则可能都存在条件, 因此无法直接做出判断, 需要查询当前资源的所有匹配的访问规则, 如果存在访问条件限制, 则需要在每次访问时检查当前用户是否满足所有的访问条件
    /// </summary>
    public bool? HasAccessCondition { get; set; }
    /// <summary>
    /// 是否实名认证
    /// </summary>
    public bool? IsRealNameAuthentication { get; set; }

    /// <summary>
    /// 获取 Code/Path 构成的缓存键, Code 存在时, 优先使用 Code
    /// </summary>
    /// <param name="withHttpMethod"></param>
    /// <returns></returns>
    public string GetCacheKey() => $"{CACHE_USER}{UserName}_Authorize_{Code}";
    /// <summary>
    /// 获取认证初始化用户基本认证状态的
    /// </summary>
    /// <returns></returns>
    public string GetAuthenticationStateCacheKey() => $"{CACHE_USER}{UserName}_AuthenticationState";
    /// <summary>
    /// 用户信息及授权缓存键名称
    /// </summary>
    /// <returns></returns>
    public string GetUserContextCacheKey() => $"{CACHE_USER}{UserName}_UserContext";
}